package main

import (
	"fmt"
	"strconv"
)

type WriterA interface {
	Write([]byte) (int, error)
}

type MyWriterA struct {
	str string
}

func (mw *MyWriterA) Write(data []byte) (int, error) {
	//类型转换
	//将byte[]强转为string；两种类型必须兼容才能强转
	mw.str += string(data)
	return len(data), nil
}

func main() {
	//GO不支持隐式类型转换，正确是b = int32(a)
	// var a int64 = 10
	// var b int32 = 0
	// b = a
	//空接口 interface{} 可以持有任何类型的值。在实际应用中，空接口经常被用来处理多种类型的值。

	var num1 int32 = 10
	var flo1 float64 = 20.0
	var change1 float64 = float64(num1)
	var change2 int32 = int32(flo1)
	fmt.Printf("显式类型转换，整数 -> 浮点数 = %f \n", change1)
	fmt.Printf("显式类型转换，浮点数 -> 整数 = %d \n", change2)
	fmt.Printf("%f / %f = %f \n", change1, flo1, change1/flo1)

	var str1 string = "1100"
	var change3 int
	var num2 int = 101010
	var change4 string
	var change5 float64
	var flag error
	change3, flag = strconv.Atoi(str1)
	if flag == nil {
		fmt.Printf("显式类型转换，字符串 -> 整型 = %d \n", change3)
	}
	change4 = strconv.Itoa(num2)
	fmt.Printf("显式类型转换，整型 -> 字符串 = %s \n", change4)
	change5, _ = strconv.ParseFloat(str1, 64)
	fmt.Printf("显式类型转换，字符串 -> 浮点数，精度为64 = %f \n", change5)
	/*
	   f float64
	       要转换的浮点数。

	   fmt byte
	       格式标志，用于指定浮点数的格式。常见的值有：
	           'f'：十进制表示（不使用指数符号）。
	           'e'：科学计数法（指数形式，小写 e）。
	           'E'：科学计数法（指数形式，大写 E）。
	           'g'：根据实际情况选择 'e' 或 'f' 格式，保证输出最简洁。
	           'G'：类似 'g'，但使用大写 E（如果是指数形式）。

	   prec int
	       精度，指定小数点后的位数：
	           如果为正数，则表示保留的具体小数位数。
	           如果为负数，则表示保留所有的有效位。

	   bitSize int
	       浮点数的位数（通常是 32 或 64）：
	           32：将浮点数解释为 float32。
	           64：将浮点数解释为 float64。
	*/
	change4 = strconv.FormatFloat(flo1, 'f', 6, 64)
	fmt.Printf("显式类型转换，浮点数 -> 字符串，十进制表示法，6位小数，精度为64 = %s \n", change4)

	//类型断言；同时返回 转换结果 和 成功与否
	var obj1 interface{} = "Hello World"
	var str2 string
	var flag2 bool
	//断言
	str2, flag2 = obj1.(string)
	if flag2 {
		fmt.Printf("类型断言成功，ojb1是string类型变量，结果值 = %s \n", str2)
	} else {
		fmt.Printf("类型断言失败")
	}

	//类型转换，涉及到多态
	// 创建一个 StringWriter 实例并赋值给 Writer 接口变量
	var w WriterA = &MyWriterA{}
	// 类型断言
	var mw *MyWriterA
	mw, flag2 = w.(*MyWriterA)
	if flag2 {
		// 修改 StringWriter 的字段
		mw.str = "Hello World"
		fmt.Printf(mw.str)
	}
}
